package svm;

import java.io.File;
import java.io.IOException;
import java.io.PrintStream;

public class run_svm {
   
   private static final String SCALE_POSTFIX = "_scale";
   private static final String MODEL_POSTFIX = ".model";
   
   /**
    * Run SVM on the given input files
    * 
    * @param train_filename the train file
    * @param test_filename the test file
    * @param out_filename the output file
    */
   public run_svm(final String train_filename, final String test_filename, final String out_filename) {
      
      final String train_scale_fn = train_filename + SCALE_POSTFIX;
      final String test_scale_fn = test_filename + SCALE_POSTFIX;
      final String model_fn = train_scale_fn + MODEL_POSTFIX;
      
      // scale the train file
      try {
         run_svm_scale(train_filename);
      }
      catch (final IOException e) {
         System.out.println(e.getMessage());
         System.exit(-1);
      }
      
      // scale the test file
      try {
         run_svm_scale(test_filename);
      }
      catch (final IOException e) {
         System.out.println(e.getMessage());
         System.exit(-1);
      }
      
      // run the train on train file
      try {
         run_svm_train(train_scale_fn);
      }
      catch (final IOException e) {
         System.out.println(e.getMessage());
         System.exit(-1);
      }
      
      // classify using svm
      try {
         run_svm_predict(test_scale_fn, model_fn, out_filename);
      }
      catch (final IOException e) {
         System.out.println(e.getMessage());
         System.exit(-1);
      }
   }
   
   /**
    * Run svm_scale on the given file
    * 
    * The scaled outfile will be in given_file + "_scale"
    * 
    * @param scale_filename the file to be scaled
    * @throws IOException 
    */
   public static void run_svm_scale(final String scale_filename) throws IOException {
      // get the original output stream
      final PrintStream p = System.out;
      
      // set the arguments for svm_scale
      final String[] argv = new String[1];
      argv[0] = scale_filename;
      
      // redirect the output to scale file
      System.setOut(new PrintStream(new File(scale_filename + SCALE_POSTFIX)));
      
      // run svm_scale
      final svm_scale s = new svm_scale();
      s.run(argv);
      
      // reset the output back to original
      System.setOut(p);
   }
   
   /**
    * Run svm_train on the given file
    * 
    * The model file will be in given_file + ".model"
    * 
    * @param train_filename the file used to train
    * @throws IOException 
    */
   public static void run_svm_train(final String train_filename) throws IOException {
      // set the arguments for svm_train
      final String[] argv = new String[1];
      argv[0] = train_filename;
      
      // run svm_train
      final svm_train t = new svm_train();
      t.run(argv);
   }
   
   /**
    * Run svm_predict using the given input files
    * 
    * @param test_filename the file that is being classified
    * @param model_filename the model file generated when svm was trained
    * @param output_filename where the classifications will be
    * @throws IOException 
    */
   public static void run_svm_predict(final String test_filename,
         final String model_filename, final String output_filename) throws IOException {
      // set the arguments for svm_predict
      final String[] argv = new String[3];
      argv[0] = test_filename;
      argv[1] = model_filename;
      argv[2] = output_filename;
      
      // run svm_predict
      final svm_predict p = new svm_predict();
      svm_predict.run(argv);
   }
   
   /**
    * This deletes the files created by run_svm
    */
   public void deleteFiles()
   {
      final File temp1 = new File("svmTrain_scale");
      final File temp2 = new File("svmFile_scale");
      final File temp3 = new File("svmTrain_scale.model");
      
      if (temp1.exists()) {
         temp1.delete();
      }
      if (temp2.exists()) {
         temp2.delete();
      }
      if (temp3.exists()) {
         temp3.delete();
      }
   }
}